﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Gsn.Base;
using Gsn.Base.Notification.Calendar;

namespace Gsn.Calendar.Controller
{
    public class CalendarController : ICalendarController
    {
        private ICalendarEngine calendarEngine_;
        private ICredentialsEngine credentials_;

        public CalendarController(ICalendarEngine calendarEngine, ICredentialsEngine credentials)
        {
            this.CalendarEngine = calendarEngine;
            this.Credentials = credentials;
        }

        #region ICalendarController Members

        public ICalendarEngine CalendarEngine
        {
            get
            {
                return calendarEngine_;
            }
            set
            {
                if (calendarEngine_ != null)
                {
                    calendarEngine_.AlarmCalendarNotification -= this.OnAlarmNotification;
                    calendarEngine_.UpdateAlarmCalendarNotification -= this.OnUpdateAlarmNotification;
                    calendarEngine_.InformativeCalendarNotification -= this.OnInformativeNotification;
                }

                calendarEngine_ = value;

                if (calendarEngine_ != null)
                {
                    calendarEngine_.AlarmCalendarNotification += this.OnAlarmNotification;
                    calendarEngine_.UpdateAlarmCalendarNotification += this.OnUpdateAlarmNotification;
                    calendarEngine_.InformativeCalendarNotification += this.OnInformativeNotification;
                }
            }
        }

        public event CalendarNotificationHandler AlarmCalendarNotification;
        public event CalendarNotificationHandler UpdateAlarmCalendarNotification;
        public event CalendarNotificationHandler InformativeCalendarNotification;

        public void ListDayCalendarEvents()
        {
            if(calendarEngine_ != null)
                calendarEngine_.ListMatchingCalendarEvents("Today's events...", DateTime.Now, DateTime.Today.AddDays(1));
        }

        public void ListTomorrowCalendarEvents()
        {
            if (calendarEngine_ != null)
                calendarEngine_.ListMatchingCalendarEvents("Tomorrow's events...", DateTime.Today.AddDays(1), DateTime.Today.AddDays(2));
        }

        public void ListWeekCalendarEvents()
        {
            if (calendarEngine_ != null)
                calendarEngine_.ListMatchingCalendarEvents("This week's events...", DateTime.Now, DateTime.Today.AddDays(8));
        }

        #endregion

        #region IController Members

        public IEngine Engine
        {
            get
            {
                return calendarEngine_;
            }
        }

        public ICredentialsEngine Credentials
        {
            get
            {
                return credentials_;
            }
            
            private set
            {
                this.credentials_ = value;
            }
        }

        public void StartEngine()
        {
            if (this.ResetUI != null)
                this.ResetUI(this, null);

            if (
                credentials_.Running &&
                credentials_.UserName != null && credentials_.Password != null)
            {
                calendarEngine_.StartEngine(credentials_.UserName, credentials_.Password);
            }
            else
                if (this.ShowCredentialsInputForm != null)
                    this.ShowCredentialsInputForm(this, null);
        }

        public void StopEngine()
        {
            if (this.ResetUI != null)
                this.ResetUI(this, null);

            calendarEngine_.StopEngine();
        }

        public void SetCredentials(String userName, String password)
        {
            credentials_.UserName = userName;
            credentials_.Password = password;
        }

        public event EventHandler ShowCredentialsInputForm;
        public event EventHandler ResetUI;

        #endregion

        private void OnAlarmNotification(ICalendarEngine source, CalendarNotification calendarNotification)
        {
            RaiseCalendarNotificationHandler(this.AlarmCalendarNotification, source, calendarNotification);
        }

        private void OnUpdateAlarmNotification(ICalendarEngine source, CalendarNotification calendarNotification)
        {
            RaiseCalendarNotificationHandler(this.UpdateAlarmCalendarNotification, source, calendarNotification);
        }

        private void OnInformativeNotification(ICalendarEngine source, CalendarNotification calendarNotification)
        {
            RaiseCalendarNotificationHandler(this.InformativeCalendarNotification, source, calendarNotification);
        }

        private void RaiseCalendarNotificationHandler(CalendarNotificationHandler toRaise, ICalendarEngine source, CalendarNotification calendarNotification)
        {
            if (toRaise != null)
                toRaise(source, calendarNotification);
        }
    }
}
